﻿/**
 * @file main.cpp
 * @date 2021/07/07 17:07
 *
 * @author harrybao (harrybao@123u.com)
 *
 * @brief
 *
 * @version v1.0.0
 *
 * @copyright Copyright © 2021 All Rights Reserved 上海欢乐互娱网络科技有限公司
 *
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author <th>Description
 * <tr><td>2021/07/07 17:07         <td>1.0.0       <td>harrybao
 * <td>创建初始版本
 * </table>
 */

#include <chrono>
#include <iostream>
#include <functional>

#include "sdk_framework_proxy.h"

#include "CreateGuildArg_struct.h"
#include "CreateGuildRes_struct.h"
#include "proxy/GuildService/guildservicebasic/GuildServiceBasic/guildservicebasic.service.GuildServiceBasic.proxy.h"

namespace kratos {
namespace util {
auto get_os_time_millionsecond() -> std::time_t {
  auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::system_clock::now().time_since_epoch())
                .count();
  return ms;
}
}  // namespace util
}  // namespace kratos

SDKFrameworkProxy sdk_framework_proxy;

bool init(int argc, char* argv[]) {

#ifdef _WIN32
  std::string shared_lib_path = "../../../win-proj/Release/sdk-framework.dll";
#else
  std::string shared_lib_path = "../../src/build/libsdk-framework.so";
#endif // _WIN32

  if (argc >= 2) {
    shared_lib_path = argv[1];
  }

  return sdk_framework_proxy.Init(shared_lib_path);
}

bool uninit() {
  return sdk_framework_proxy.Uninit();
}

void run() {
  std::cout << "run start..." << '\n';
  // 创建中台连接对象
  auto* platform_link_ptr = sdk_framework_proxy.CreatePlatformLink();
  
  const std::string ip = std::string("127.0.0.1");
  constexpr uint32_t port = 10001;

  // 初始化SDK环境
  platform_link_ptr->Init();
  // 连接中台服务IP和端口
  platform_link_ptr->Connect(ip, port);
  //  更新处理网络连接事件
  auto start = kratos::util::get_os_time_millionsecond();
  for (;;) {
    platform_link_ptr->Update();
    auto now = kratos::util::get_os_time_millionsecond();
    if (now - start > 2000) {
      break;
    }
  }
  {
    // 创建中台服务代理对象
    auto guild_service_basic_prx_ptr =
        platform_link_ptr->CreateProxy<GuildServiceBasicProxy>();
    if (!guild_service_basic_prx_ptr) {
      std::cerr << "guild_service_basic_prx_ptr == nullptr" << '\n';
    }
    assert(guild_service_basic_prx_ptr);

    // 执行中台服务提供的接口功能
    uint64_t guild_id = 0;

    CreateGuildArg arg;
    arg.token = 1000;
    arg.name = "guild" + std::to_string(arg.token);

    bool use_coro = false;
    if (use_coro) {
      // platform_link_ptr->CoroStart([&](void*) {
      //   try {
      //     auto res = guild_service_basic_prx_ptr->CreateGuild(arg);
      //     if (res) {
      //       std::cout << "CreateGuild"
      //                 << " 结果:" << static_cast<int>(res->result)
      //                 << " 公会id:" << res->id << '\n';
      //       if (res->result == guildservicebasic_cpp::ErrorCode::ERR_SUCCESS)
      //       {
      //         guild_id = res->id;
      //       }
      //     }
      //   } catch (std::exception& ex) {
      //     std::cerr << "CreateGuild exception:" << ex.what() << std::endl;
      //   }
      // });
    } else {
      guild_service_basic_prx_ptr->CreateGuild(
          arg, [&](const CreateGuildRes& res, rpc::RpcError err) {
            std::cout << "CreateGuild"
                      << " Rpc结果:" << static_cast<uint32_t>(err)
                      << " 结果:" << static_cast<int>(res.result)
                      << " 公会id:" << res.id << '\n';
            if (res.result == guildservicebasic_cpp::ErrorCode::ERR_SUCCESS) {
              guild_id = res.id;
            }
          });
    }
    // 处理网络收发数据和RPC事件
    start = kratos::util::get_os_time_millionsecond();
    for (;;) {
      platform_link_ptr->Update();
      auto now = kratos::util::get_os_time_millionsecond();
      if (now - start > 2000) {
        break;
      }
    }
  }

  // 退出程序时销毁SDK环境
  // proxy 必须在platform_link::Uninit之前销毁
  // 原因是：proxy->delete->rpc::free，platform_link->~rpc
  platform_link_ptr->UnInit();

  sdk_framework_proxy.DestroyPlatformLink(platform_link_ptr);
  platform_link_ptr = nullptr;

  std::cout << "run finished." << '\n';
}

int main(int argc, char* argv[]) {
  if (!init(argc, argv)) {
    return 1;
  }

  run();

  if (!uninit()) {
    return 1;
  }

  return 0;
}